package com.wzg.ttstestandroid.SyntheticSpeech;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import androidx.annotation.NonNull;

import com.baidu.tts.chainofresponsibility.logger.LoggerProxy;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.orhanobut.logger.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 * You might think you can read it or optimize it, but no,you're wrong, Please  believe me. You'll see to do.
 * author:wzg
 * createTime: 2022/1/15/015 14:50
 * desc: 基于tts语音合成的工具类
 */
public class SyntheticSpeechUtils {


    private final String appId = "25511946";
    private final String appKey = "0EofjrtQMDqXQdfvKkLG8veo";
    private final String secretKey = "DemR0StdqbcxnZpZRaHr5yvuRqcNoQiG";

    // TtsMode.MIX; 离在线融合，在线优先； TtsMode.ONLINE 纯在线； 没有纯离线
    private final TtsMode ttsMode = TtsMode.ONLINE;
    protected SpeechSynthesizer mSpeechSynthesizer;

    private static SyntheticSpeechUtils instance;

    private SyntheticSpeechUtils() {
    }

    public static SyntheticSpeechUtils getInstance() {
        if (instance == null) {
            synchronized (SyntheticSpeechUtils.class) {
                instance = new SyntheticSpeechUtils();
            }
        }
        return instance;
    }

    /**
     * 注意此处为了说明流程，故意在UI线程中调用。
     * 实际集成中，该方法一定在新线程中调用，并且该线程不能结束。具体可以参考NonBlockSyntherizer的写法
     */
    public void initTTs(Context mContext) {
        LoggerProxy.printable(true); // 日志打印在logcat中
        // 日志更新在UI中，可以换成MessageListener，在logcat中查看日志
        SpeechSynthesizerListener listener = new UiMessageListener(new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if (msg.obj != null) {
                    Logger.e(msg.obj.toString());
                }
            }
        });
        // 1. 获取实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(mContext);
        // 2. 设置listener
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);
        // 3. 设置appId，appKey.secretKey
        int result = mSpeechSynthesizer.setAppId(appId);
        checkResult(result, "setAppId");
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
        checkResult(result, "setApiKey");
        // 5. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声  3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
        // mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL); // 调整音频输出
        // x. 额外 ： 自动so文件是否复制正确及上面设置的参数
        Map<String, String> params = new HashMap<>();
        // 检测参数，通过一次后可以去除，出问题再打开debug
        InitConfig initConfig = new InitConfig(appId, appKey, secretKey, ttsMode, params, listener);
        TTSAutoCheck.getInstance(mContext)
                .check(initConfig, new Handler(Looper.getMainLooper()) {
                    @Override
                    // 开新线程检查，成功后回调
                    public void handleMessage(Message msg) {
                        if (msg.what == 100) {
                            TTSAutoCheck autoCheck = (TTSAutoCheck) msg.obj;
                            synchronized (autoCheck) {
                                String message = autoCheck.obtainDebugMessage();
                                Logger.e(message);
                            }
                        }
                    }
                });

        // 6. 初始化
        result = mSpeechSynthesizer.initTts(ttsMode);
        checkResult(result, "initTts");

    }

    private void checkResult(int result, String method) {
        if (result != 0) {
            Logger.e("error code :" + result + " method:" + method);
        }
    }

    /**
     * 根据文字说话
     */
    public void speak(String txt) {
        if (mSpeechSynthesizer == null) {
            Logger.e("[ERROR], 初始化失败");
            return;
        }
        int result = mSpeechSynthesizer.speak(txt);
        Logger.e("合成并播放 按钮已经点击");
        checkResult(result, "speak");
    }

    /**
     * 销毁
     */
    public void dispose() {
        if (mSpeechSynthesizer != null) {
            mSpeechSynthesizer.stop();
            mSpeechSynthesizer.release();
            mSpeechSynthesizer = null;
            Logger.e("释放资源成功");
        }
    }

    /**
     */
    private void stop() {
        Logger.e("停止合成引擎 按钮已经点击");
        int result = mSpeechSynthesizer.stop();
        checkResult(result, "stop");
    }


}
